package com.jzo2o.foundations.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jzo2o.api.foundations.dto.ServeItemSimpleDTO;
import com.jzo2o.api.foundations.dto.response.ServeTypeCategoryResDTO;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.foundations.constants.RedisConstants;
import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.mapper.RegionMapper;
import com.jzo2o.foundations.mapper.ServeItemMapper;
import com.jzo2o.foundations.mapper.ServeMapper;
import com.jzo2o.foundations.mapper.ServeTypeMapper;
import com.jzo2o.foundations.model.domain.Region;
import com.jzo2o.foundations.model.domain.Serve;
import com.jzo2o.foundations.model.domain.ServeItem;
import com.jzo2o.foundations.model.domain.ServeType;
import com.jzo2o.foundations.model.dto.response.ServeAggregationSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeCategoryResDTO;
import com.jzo2o.foundations.model.dto.response.ServeSimpleResDTO;
import com.jzo2o.foundations.service.HomeService;
import com.jzo2o.foundations.service.IRegionService;
import com.jzo2o.redis.config.RedisConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class HomeServiceImpl implements HomeService {

    @Resource
    private IRegionService regionService;

    @Resource
    private ServeMapper serveMapper;
    @Autowired
    private RedisProperties redisProperties;
    @Autowired
    private RedisConfiguration redisConfiguration;
    @Autowired
    private RegionMapper regionMapper;
    @Autowired
    private ServeItemMapper serveItemMapper;

    @Autowired
    private ServeTypeMapper serveTypeMapper;


    /**
     * 首页服务列表
     *
     * @param regionId
     * @return
     */
    @Override
    @Caching(
            cacheable = {
                    @Cacheable(value = RedisConstants.CacheName.SERVE_ICON, key = "#regionId", unless = "#result!=0", cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES),
                    @Cacheable(value = RedisConstants.CacheName.SERVE_ICON, key = "#regionId", unless = "#result==0", cacheManager = RedisConstants.CacheManager.FOREVER)
            }
    )
    public List<ServeCategoryResDTO> firstPageServeList (Long regionId) {
        //1.检查区域状态是否启用
        Region region = regionService.getById (regionId);
        if (region == null || region.getActiveStatus () != FoundationStatusEnum.ENABLE.getStatus ()) {
            throw new ForbiddenOperationException ("区域不存在或状态不对");
        }
        //2.根据城市编码查询所有服务类型和服务列表
        List<ServeCategoryResDTO> serveTypeAndServeList = serveMapper.getServeTypeAndServeList (regionId);
        if (ObjectUtil.isEmpty (serveTypeAndServeList)) {
            return Collections.emptyList ();
        }
        //3.服务类型取前两个，每个类型下服务项取前4个
        Integer serveTypeSize = serveTypeAndServeList.size () >= 2 ? 2 : serveTypeAndServeList.size ();
        List<ServeCategoryResDTO> serveCategoryResDTOS = new ArrayList<> (serveTypeAndServeList.subList (0, serveTypeSize));
        serveCategoryResDTOS.forEach (serveType -> {
            List<ServeSimpleResDTO> serveResDTOList = serveType.getServeResDTOList ();
            Integer serveSize = serveResDTOList.size () >= 4 ? 4 : serveResDTOList.size ();

            List<ServeSimpleResDTO> serveSimpleResDTOS = new ArrayList<> (serveResDTOList.subList (0, serveSize));
            serveResDTOList = serveResDTOList.subList (0, serveSize);
            serveType.setServeResDTOList (serveSimpleResDTOS);
        });
        return serveCategoryResDTOS;
    }

    @Override
    @Caching(
            cacheable = {
                    @Cacheable(value = RedisConstants.CacheName.SERVE_TYPE, key = "#regionId", unless = "#result!=0", cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES),
                    @Cacheable(value = RedisConstants.CacheName.SERVE_TYPE, key = "#regionId", unless = "#result==0", cacheManager = RedisConstants.CacheManager.FOREVER),
            }
    )
    public List<ServeTypeCategoryResDTO> serveTypeList (Long regionId) {
        Region region = regionService.getById (regionId);
        if (region == null || region.getActiveStatus () != FoundationStatusEnum.ENABLE.getStatus ()) {
            throw new ForbiddenOperationException ("区域不存在或状态不对");
        }

        List<Serve> serves = serveMapper.selectList (Wrappers.<Serve>lambdaQuery ()
                .eq (Serve::getRegionId, regionId)
                .eq (Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus ()));


        List<ServeItem> serveItems = new ArrayList<> ();
        for (Serve serve : serves) {
            Long serveItemId = serve.getServeItemId ();
            ServeItem serveItem = serveItemMapper.selectById (serveItemId);
            if (serveItem.getActiveStatus () == FoundationStatusEnum.ENABLE.getStatus ()) {
                serveItems.add (serveItem);
            }
        }
        List<ServeType> serveTypes = new ArrayList<> ();
        for (ServeItem serveItem : serveItems) {
            ServeType serveType = serveTypeMapper.selectById (serveItem.getServeTypeId ());
            if (serveType.getActiveStatus () == FoundationStatusEnum.ENABLE.getStatus ()) {
                serveTypes.add (serveType);
            }
        }
        serveTypes = serveTypes.stream ().distinct ().collect (Collectors.toList ());
        List<ServeTypeCategoryResDTO> categoryResDTOS = new ArrayList<> ();
        for (ServeType serveType : serveTypes) {
            ServeTypeCategoryResDTO serveTypeCategoryResDTO = new ServeTypeCategoryResDTO ();
            serveTypeCategoryResDTO.setServeTypeId (serveType.getId ());
            serveTypeCategoryResDTO.setServeTypeName (serveType.getName ());
            serveTypeCategoryResDTO.setServeTypeImg (serveType.getImg ());
            serveTypeCategoryResDTO.setServeTypeSortNum (serveType.getSortNum ());
            categoryResDTOS.add (serveTypeCategoryResDTO);
        }
        return categoryResDTOS;
    }

    @Override
    @Caching(
            cacheable = {
                    @Cacheable(value = RedisConstants.CacheName.HOT_SERVE, key = "#regionId", unless = "#result!=0", cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES),
                    @Cacheable(value = RedisConstants.CacheName.HOT_SERVE, key = "#regionId", unless = "#result==0", cacheManager = RedisConstants.CacheManager.FOREVER)
            }
    )
    public List<ServeAggregationSimpleResDTO> hotServeList (Long regionId) {
        Region region = regionService.getById (regionId);
        if (region == null || region.getActiveStatus () != FoundationStatusEnum.ENABLE.getStatus ()) {
            throw new ForbiddenOperationException ("区域不存在或状态不对");
        }

        List<Serve> serves = serveMapper.selectList (Wrappers.<Serve>lambdaQuery ()
                .eq (Serve::getRegionId, regionId)
                .eq (Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus ())
                .eq (Serve::getIsHot, 1));


//        List<ServeItem> serveItems = new ArrayList<> ();
        List<ServeAggregationSimpleResDTO> serveAggregationSimpleResDTO = new ArrayList<> ();
        for (Serve serve : serves) {
            Long serveItemId = serve.getServeItemId ();
            ServeItem serveItem = serveItemMapper.selectById (serveItemId);
            if (serveItem.getActiveStatus () == FoundationStatusEnum.ENABLE.getStatus ()) {
                ServeAggregationSimpleResDTO serveAggregationSimpleRes = new ServeAggregationSimpleResDTO ();
                serveAggregationSimpleRes.setCityCode (serve.getCityCode ());
                serveAggregationSimpleRes.setServeItemName (serveItem.getName ());
                serveAggregationSimpleRes.setServeItemId (serveItem.getId ());
                serveAggregationSimpleRes.setUnit (serveItem.getUnit ());
                serveAggregationSimpleRes.setDetailImg (serveItem.getDetailImg ());
                serveAggregationSimpleRes.setPrice (serve.getPrice ());
                serveAggregationSimpleRes.setServeItemImg (serveItem.getImg ());
                serveAggregationSimpleRes.setId (serve.getId ());
                serveAggregationSimpleResDTO.add (serveAggregationSimpleRes);
            }
        }
        return serveAggregationSimpleResDTO;
    }

    @Override
    public ServeAggregationSimpleResDTO getById (Long id) {

        Serve serve = getServeById (id);
        if (ObjectUtils.isEmpty (serve)) {
            throw new ForbiddenOperationException ("服务不存在");
        }
        ServeAggregationSimpleResDTO serveAggregationSimpleResDTO = BeanUtils.copyBean (serve, ServeAggregationSimpleResDTO.class);
        Long serveItemId = serve.getServeItemId ();
        ServeItem serveItem = getServeItemById (serveItemId);
        if (ObjectUtils.isNotEmpty (serveItem)) {
            serveAggregationSimpleResDTO.setDetailImg (serveItem.getDetailImg ());
            serveAggregationSimpleResDTO.setServeItemImg (serveItem.getImg ());
            serveAggregationSimpleResDTO.setServeItemName (serveItem.getName ());
            serveAggregationSimpleResDTO.setUnit (serveItem.getUnit ());
        }
        return serveAggregationSimpleResDTO;
    }

    @Caching(
            cacheable = {
                    @Cacheable(value = RedisConstants.CacheName.SERVE_ITEM, key = "#serveItemId", unless = "#result!=0", cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES),
                    @Cacheable(value = RedisConstants.CacheName.SERVE_ITEM, key = "#serveItemId", unless = "#result==0", cacheManager = RedisConstants.CacheManager.FOREVER)
            }
    )
    @Override
    public ServeItem getServeItemById (Long serveItemId) {
        return serveItemMapper.selectById (serveItemId);
    }

    @Caching(
            cacheable = {
                    @Cacheable(value = RedisConstants.CacheName.SERVE, key = "#id", unless = "#result!=0", cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES),
                    @Cacheable(value = RedisConstants.CacheName.SERVE, key = "#id", unless = "#result==0", cacheManager = RedisConstants.CacheManager.FOREVER)
            }
    )
    @Override
    public Serve getServeById (Long id) {
        return serveMapper.selectById (id);
    }

    @Override
    public List<ServeItemSimpleDTO> search (String cityCode, Long serveTypeId) {
        List<Serve> serves = serveMapper.selectList (Wrappers.<Serve>lambdaQuery ().eq (Serve::getCityCode, cityCode)
                .eq (Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus ()));
        if (ObjectUtil.isEmpty (serves)) {
            return Collections.emptyList ();
        }
        List<ServeItemSimpleDTO> serveItemSimpleDTOList = new ArrayList<> ();
        for (Serve serve : serves) {
            ServeItem serveItem = serveItemMapper.selectById (serve.getServeItemId ());
            if(serveItem==null){
                continue;
            }
            if (Objects.equals (serveItem.getServeTypeId (), serveTypeId) && serveItem.getActiveStatus () == FoundationStatusEnum.ENABLE.getStatus ()) {
                ServeItemSimpleDTO serveItemSimpleDTO = new ServeItemSimpleDTO ();
                serveItemSimpleDTO.setServeItemId (serveItem.getId ());
                serveItemSimpleDTO.setServeItemName (serveItem.getName ());
                serveItemSimpleDTOList.add (serveItemSimpleDTO);
            }
        }
        return serveItemSimpleDTOList;
    }
//    @Override
//    public List<ServeCategoryResDTO> serveTypeList(Long regionId) {
//        //1.检查区域状态是否启用
//        Region region = regionService.getById(regionId);
//        if(region==null || region.getActiveStatus()!=2){
//            throw new ForbiddenOperationException("区域不存在或状态不对");
//        }
//
//        //2.根据城市编码查询所有服务类型和服务列表
//        List<ServeCategoryResDTO> serveTypeAndServeList = serveMapper.getServeTypeAndServeList(regionId);
//        if (ObjectUtil.isEmpty(serveTypeAndServeList)) {
//            return Collections.emptyList();
//        }
//        return serveTypeAndServeList;
//    }
}